home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 25
/
Cream of the Crop 25.iso
/
faq
/
wdj0597.zip
/
SDKANN.ZIP
/
SOURCE.ZIP
/
ANNTATER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-01-09
|
38KB
|
1,231 lines
#include <assert.h>
#include <ctype.h>
#include "anntater.h"
#include <windowsx.h>
#include <commdlg.h>
#include <dir.h>
#include <direct.h>
#include <stdlib.h>
#include <string.h>
#if defined(__WIN32__) || defined(__WIN32)
# define GetWindowParent(hwnd) ((HWND)GetWindowLong(hwnd, GWL_HWNDPARENT))
#else
# define GetWindowParent(hwnd) ((HWND)GetWindowWord(hwnd, GWW_HWNDPARENT))
#endif
extern void InitCheckList(HINSTANCE);
int InCopy = FALSE;
int StopLoop = FALSE;
BOOL EnableControl(HWND Dialog, int Id, int On)
{
HWND Child = GetDlgItem(Dialog, Id);
if(Child != 0)
return EnableWindow(Child, On);
else
return FALSE;
}
void MessagePump(int Time = 100)
{
DWORD StartTime = GetTickCount();
MSG Msg;
while((GetTickCount() - StartTime) < Time)
while(PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE))
{
switch(Msg.message)
{
case WM_KEYDOWN :
case WM_LBUTTONDOWN :
case WM_RBUTTONDOWN :
case WM_MBUTTONDOWN :
StopLoop = TRUE;
}
GetMessage(&Msg, NULL, 0, 0);
DispatchMessage(&Msg);
}
}
LRESULT SendCommand(HWND Dialog, HWND Control, int Id, int Command)
{
LRESULT Result = TRUE;
#if defined(__WIN32__) || defined(__WIN32)
Result = SendMessage(Dialog, WM_COMMAND, MAKEWPARAM(Id, Command),
(LPARAM)Control);
#else
Result = SendMessage(Dialog, WM_COMMAND, (WPARAM)Id,
MAKELPARAM(Control, Command));
#endif
return Result;
}
LRESULT PostCommand(HWND Dialog, HWND Control, int Id, int Command)
{
LRESULT Result = TRUE;
#if defined(__WIN32__) || defined(__WIN32)
Result = PostMessage(Dialog, WM_COMMAND, MAKEWPARAM(Id, Command),
(LPARAM)Control);
#else
Result = PostMessage(Dialog, WM_COMMAND, (WPARAM)Id,
MAKELPARAM(Control, Command));
#endif
return Result;
}
int PushButton(HWND Dialog, int ButtonId, int Post = FALSE)
{
int Result = FALSE;
HWND Button = GetDlgItem(Dialog, ButtonId);
if(Button)
{
if(Post)
{
PostCommand(Dialog, Button, ButtonId, BN_CLICKED);
MessagePump();
}
else
SendCommand(Dialog, Button, ButtonId, BN_CLICKED);
Result = TRUE;
}
return Result;
}
typedef BOOL (WINAPI*SETFUNC)(HWND Window);
int MakeActive(HWND Window)
{
#if defined(__WIN32__) || defined(__WIN32)
SetForegroundWindow(Window);
#else
#define USER() GetModuleHandle("USER")
static int Loaded = FALSE;
static SETFUNC SetForegroundWindow;
if(!Loaded)
{
SetForegroundWindow = (SETFUNC)GetProcAddress(USER(),"SetForegroundWindow");
Loaded = TRUE;
}
if(SetForegroundWindow)
SetForegroundWindow(Window);
else
SetActiveWindow(Window);
#endif
MessagePump(300);
return TRUE;
}
char SelectedFile[512];
// name of main dialog box
#define MAIN_DLG "MainDialog"
HINSTANCE CurrentInstance; // often need global for this
/* GetHelpDialog() - locate a dialog belonging to the help window
*
* Sometimes we need to find one of WinHelp's dialog windows.
* This function locates a top-level window whose parent is the
* WinHelp window. You can also specify the Id of a child window,
* in case you need to distinguish between two WinHelp dialogs.
*/
HWND GetHelpDialog(int ChildId=0)
{
HWND Help = FindWindow("MS_WINHELP", NULL);
HWND Rover = GetDesktopWindow();
Rover = GetWindow(Rover, GW_CHILD);
while(Rover)
{
HWND Parent = GetWindowParent(Rover);
HWND GrandParent = 0;
if(Parent)
GrandParent = GetWindowParent(Parent);
if(Parent == Help || GrandParent == Help)
{
if(!ChildId || GetDlgItem(Rover, ChildId))
return Rover;
}
Rover = GetWindow(Rover, GW_HWNDNEXT);
}
return 0;
}
#include <io.h>
int WDJ_PathFind(const char *InPath, const char *File,
char *OutPath, int Maxlen)
{
/* sanity check */
if(InPath && *InPath)
{
// for each directory in the path
while(*InPath)
{
char Dir[256];
const char*Rover = strchr(InPath, ';');
int Len = Rover ? (Rover - InPath) : strlen(InPath);
memcpy(Dir, InPath, Len);
Dir[Len] = '\0';
strcat(Dir, "\\");
strcat(Dir, File);
if(access(Dir, 0) != -1)
{
if(OutPath && Maxlen)
{
strcpy(OutPath, Dir);
return TRUE;
}
}
InPath += Len+1;
}
}
return FALSE;
}
const char* GetPath()
{
#if defined(__WIN32) || defined(__WIN32__)
static char Path[512];
GetEnvironmentVariable("Path", Path, sizeof(Path));
return Path;
#else
const char* Env = GetDOSEnvironment();
while(Env && *Env)
{
if(!strncmp(Env, "PATH=", 5))
return Env + 5;
else
Env += strlen(Env)+1;
}
return 0;
#endif
}
/* FindHelpFile - user selected new .hlp, try to locate it
*
* When the user picks a different .hlp to annotate, this
* function tries to locate that .hlp file. First, it tries
* the last known path for that .hlp file, which would be
* recorded in the .ini file. If that fails, it then searches
* the DOS environment path. If that fails, then all the other
* buttons are disabled except for the one that lets the user
* tell us where the .hlp file is.
*/
int FindHelpFile(HWND Dialog, const char*File)
{
int Result = TRUE;
char Found[512];
GetPrivateProfileString("AnnTater", File, "", Found, sizeof(Found), "wdj.ini");
// if not found in .ini file
if(Found[0] == '\0')
{
const char*Search = GetPath();
if(!WDJ_PathFind(Search, File, Found, sizeof(Found)))
Result = FALSE;
}
if(Result == TRUE)
{
EnableControl(Dialog, ID_COPY, TRUE);
EnableControl(Dialog, ID_SELECTALL, TRUE);
SetDlgItemText(Dialog, ID_HELP_PATH, Found);
strcpy(SelectedFile, Found);
}
else
{
EnableControl(Dialog, ID_COPY, FALSE);
EnableControl(Dialog, ID_SELECTALL, FALSE);
SetDlgItemText(Dialog, ID_HELP_PATH,
"<press Locate button to specify path for this file>");
}
return Result;
}
// load RCDATA resource, assumes string terminated by 2 NULLs
int GetResource(const char *Name, char *Buffer)
{
int Len;
char *Data;
HGLOBAL Handle;
HRSRC Pos = FindResource(CurrentInstance, Name, RT_RCDATA);
if(Pos == NULL)
return FALSE;
Handle = LoadResource(CurrentInstance, Pos);
Data = (char *)LockResource(Handle);
for(Len=0; Data[Len] || Data[Len+1]; ++Len)
;
memcpy(Buffer, Data, Len+1);
UnlockResource(Handle);
FreeResource(Handle);
return Len;
}
char* StrDup(const char* S)
{
size_t Len = strlen(S) + 1;
char* Result = new char[Len];
if(Result)
memcpy(Result, S, Len);
return Result;
}
int IsHelp32 = FALSE;
int InitHelpVersion()
{
size_t Len;
HINSTANCE Inst;
char Path[512];
HWND Help = FindWindow("MS_WINHELP", NULL);
Inst = GetWindowInstance(Help);
Path[0] = '\0';
GetModuleFileName(Inst, Path, sizeof(Path));
Len = strlen(Path);
/* 32-bit module name is "WINHLP32.EXE" */
if(Len >= 12 && Path[Len-6] == '3' && Path[Len-5] == '2')
IsHelp32 = TRUE;
//MessageBox(NULL, Path, IsHelp32?"WINHLP32":"WinHelp", MB_OK);
return TRUE;
}
int WDJ_EmptyClipboard(void)
{
HWND ClipWin = GetDesktopWindow(); /* any window will do */
if(OpenClipboard(ClipWin))
{
EmptyClipboard();
CloseClipboard();
return TRUE;
}
return FALSE;
}
int WDJ_SetClipboardText(char *Buffer)
{
int Result = FALSE;
HWND ClipWin = GetDesktopWindow(); /* any window will do */
if(OpenClipboard(ClipWin))
{
size_t Len = strlen(Buffer) + 1;
HGLOBAL ClipData = GlobalAlloc(GHND, Len);
if(ClipData != 0)
{
char *P = (char*)GlobalLock(ClipData);
strcpy(P, Buffer);
GlobalUnlock(ClipData);
if(SetClipboardData(CF_TEXT, ClipData))
Result = TRUE;
}
CloseClipboard();
}
return Result;
}
int WDJ_GetClipboardText(char *Buffer, UINT MaxSize)
{
int Result = FALSE;
HWND ClipWin = GetDesktopWindow(); /* any window will do */
if(OpenClipboard(ClipWin))
{
HGLOBAL ClipData;
ClipData = (HGLOBAL)GetClipboardData(CF_TEXT);
if(ClipData != NULL)
{
char *P = (char*)GlobalLock(ClipData);
if(P != 0)
{
UINT Len = strlen(P) + 1;
if(MaxSize > 0)
{
if(MaxSize < Len)
Len = MaxSize;
if(Len > 0)
memcpy(Buffer, P, Len-1);
Buffer[Len] = '\0';
}
Result = TRUE;
}
GlobalUnlock(ClipData);
}
CloseClipboard();
}
return Result;
}
//*********************************************************
class TTopic
{
public:
TTopic() : RsrcId_(0) {}
~TTopic() {}
int Load(HINSTANCE Inst, int TopicNum);
int IsFor(const char*FileName);
int GetFile(char* Buffer, int Max)
{ return GetIt(0, Buffer, Max); }
int GetDisplayTitle(char* Buffer, int Max)
{ return GetIt(1, Buffer, Max); }
int GetKeyword(char* Buffer, int Max);
int GetTitle(char* Buffer, int Max)
{ return GetIt(3, Buffer, Max); }
int GetText(char* Buffer, int Max)
{ return GetIt(4, Buffer, Max); }
void Clear() { RsrcId_ = 0; TopicNum_ = 0; }
private:
int GetIt(int Pos, char*Buffer, int Max);
HRSRC RsrcId_;
int TopicNum_;
};
TTopic ThisTopic;
int TTopic::GetKeyword(char* Buffer, int Max)
{
*Buffer = '\0';
int Result= GetIt(2, Buffer, Max);
// chop off any MSDN-style search terms
char *Extra = strstr(Buffer, " AND");
if(Extra)
*Extra = '\0';
return Result;
}
int TTopic::Load(HINSTANCE Inst, int TopicId)
{
TopicNum_ = TopicId;
RsrcId_ = FindResource(Inst,
MAKEINTRESOURCE(TopicId), RT_RCDATA);
return RsrcId_ != NULL;
}
int TTopic::IsFor(const char* FileName)
{
if(!RsrcId_)
return FALSE;
char File[128];
GetFile(File, sizeof(File));
return !strcmpi(FileName, File);
}
int TTopic::GetIt(int Pos, char* Out, int Max)
{
int Result = FALSE;
if(!RsrcId_)
return Result;
char* Buffer = new char[1024*8];
if(Buffer)
{
if(GetResource(MAKEINTRESOURCE(TopicNum_), Buffer))
{
const char*Rover = Buffer;
while(Pos--)
Rover = Rover + strlen(Rover)+1;
if(Out && Max > 0)
{
for(int i=0; i < Max && *Rover; ++i)
*Out++ = *Rover++;
*Out = '\0';
Result = TRUE;
}
}
delete[] Buffer;
}
return Result;
}
//*********************************************************
typedef BOOL (*DLGCMDHANDLER)(HWND Dialog, UINT Notify,
int ControlId, HWND Control);
BOOL DialogCommand(DLGCMDHANDLER Handler, HWND Dialog,
WPARAM Param1, LPARAM Param2)
{
UINT Notify;
UINT ControlId;
HWND Control;
#if defined(__WIN32__)
Notify = HIWORD(Param1);
ControlId = LOWORD(Param1);
Control = (HWND)Param2;
#else
Notify = HIWORD(Param2);
ControlId = Param1;
Control = (HWND)LOWORD(Param2);
#endif
return Handler(Dialog, Notify, (int)ControlId, Control);
}
// FindHelp - locate a standalone helpfile window!
HWND FindHelp(void)
{
return FindWindow("MS_WINHELP", NULL);
}
int LoadTitles(HWND Listbox, const char*File)
{
char *Buffer = (char *)malloc(1024*16);
char *Title = Buffer;
SendMessage(Listbox, WM_SETREDRAW, 0, 0);
SendMessage(Listbox, LB_RESETCONTENT, 0, 0);
TTopic Topic;
for(int i=1; Topic.Load(CurrentInstance, i); ++i)
{
if(Topic.IsFor(File))
{
Topic.GetDisplayTitle(Title, 1024);
int Index = SendMessage(Listbox, LB_ADDSTRING, 0, (LPARAM)Title);
if(Index != CB_ERR)
{
ListBox_SetItemData(Listbox, Index, i);
}
}
}
SendMessage(Listbox, WM_SETREDRAW, 1, 0);
free(Buffer);
return TRUE;
}
enum { CANCEL = 9, REPLACE = 10, APPEND = 11,
ASK = 12, SKIP = 13 } Always=ASK;
#ifdef __BORLANDC__
# pragma argsused
#endif
static BOOL OnClobberDialogCommand(HWND Dialog, UINT Notify,
int ControlId, HWND Control)
{
if(ControlId == IDCANCEL)
{
EndDialog(Dialog, Always = CANCEL);
return FALSE;
}
else if(ControlId == ID_SKIP)
{
EndDialog(Dialog, SKIP);
if(IsDlgButtonChecked(Dialog, ID_STOPASKING))
Always = CANCEL;
return FALSE;
}
else if(ControlId == ID_REPLACE)
{
EndDialog(Dialog, REPLACE);
if(IsDlgButtonChecked(Dialog, ID_STOPASKING))
Always = REPLACE;
}
else if(ControlId == ID_APPEND)
{
EndDialog(Dialog, APPEND);
if(IsDlgButtonChecked(Dialog, ID_STOPASKING))
Always = APPEND;
}
return FALSE;
}
BOOL CALLBACK __export ClobberDialog(HWND Dialog, UINT Message,
WPARAM Param1, LPARAM Param2)
{
if(Message == WM_INITDIALOG)
{
return TRUE;
}
else if(Message == WM_COMMAND)
{
return DialogCommand(OnClobberDialogCommand,
Dialog, Param1, Param2);
}
return FALSE; /* FALSE == we didn't process msg */
}
/* MatchTopic32 - Handle partial match for 32-bit WinHelp
*
* When a given keyword does not uniquely identify a help topic,
* this function gets called to attempt to locate the correct
* topic.
*/
BOOL MatchTopic32(HWND Dialog, HWND SearchDlg, const char*Title)
{
int Result = TRUE;
// first, see if it is the "Topics Found" dialog
if(GetDlgItem(SearchDlg, 0x6F))
{
/* it is the "Topics Found" dialog, so we have to
* search the listed topic titles for a match
*/
HWND Topics = GetDlgItem(SearchDlg, 0x6F);
int Count = ListBox_GetCount(Topics);
for(int i=0; i < Count; ++i)
{
char Item[256];
memset(Item, 0, sizeof(Item));
ListBox_GetText(Topics, i, Item);
// if we found a match
if(!strcmpi(Item, Title))
{
// then select it and press display button
ListBox_SetCurSel(Topics, i);
PushButton(SearchDlg, 0x01, TRUE);
return TRUE;
}
}
// no match, have to fail
PushButton(Topics, IDCANCEL, TRUE);
return FALSE;
}
// now we have to see if we have a match
// push the "Display" button
PushButton(SearchDlg, 0x01, TRUE);
// at this point, either topics dialog or msg box will appear
int j;
for(j=0; j < 5; ++j)
{
if(GetHelpDialog(0x6F))
break;
else if(GetHelpDialog(0x0A))
break;
MessagePump(500);
}
if(j >= 5)
{
MessageBox(NULL, "Could not synch with WinHelp!", "AnnTater", MB_OK);
return FALSE;
}
HWND MsgBox = GetHelpDialog(0x0A);
if(MsgBox)
{
SetWindowText(Dialog, "error message box appeared");
// "The word you have typed is not in the index..."
MessagePump();
PushButton(MsgBox, IDCANCEL, TRUE);
MessagePump();
PushButton(SearchDlg, IDCANCEL, TRUE);
MessagePump();
return FALSE;
}
SetWindowText(Dialog, "error message box did not appear");
// see if that produced a list of matches
HWND TopicsDlg = GetHelpDialog(0x6F);
// if no matches
if(!TopicsDlg)
{
HWND MsgBox = GetHelpDialog(0x0A);
if(MsgBox)
{
SetWindowText(Dialog, "About to push button!");
MessagePump(3000);
PushButton(MsgBox, IDCANCEL, TRUE);
MessagePump();
SetWindowText(Dialog, "pushed button!");
MessagePump(3000);
Result = FALSE;
}
PushButton(SearchDlg, IDCANCEL);
MessagePump();
}
return Result;
}
/* MatchTopic16 - Handle partial match for 16-bit WinHelp
*
* When a given keyword does not uniquely identify a help topic,
* this function gets called to attempt to locate the correct
* topic.
*/
BOOL MatchTopic16(HWND Dialog, HWND SearchDlg, const char* Title,
const char*Keyword)
{
/*
* It turns out that 16-bit WinHelp will not produce an
* error if you press the Search button and an incorrect
* keyword is displayed. Therefore, we have to be a little
* tricky to figure out if our keyword has an exact match.
* The keywords are displayed in a custom listbox, not a
* standard one, so I can't easily check the current selection.
* Instead, I first press the Show Topics button, and WinHelp
* responds by wiping out my keyword with the closest matching
* keyword. By checking the edit box to see if my keyword stays
* the same, I can tell whether I had an exact match or not...
*/
SetWindowText(Dialog, "Push Show Topics button");
// Press Show Topics button
PushButton(SearchDlg, 0x74, TRUE);
HWND Edit = GetDlgItem(SearchDlg, 0x66);
if(!Edit)
{
MessageBox(Dialog, "Search dialog not in expected format!", "AnnTater", MB_OK);
PushButton(SearchDlg, IDCANCEL, TRUE);
return FALSE;
}
char MatchKey[256];
SendMessage(Edit, WM_GETTEXT, 255, (LPARAM)MatchKey);
// if no exact match for our keyword
if(strcmpi(MatchKey, Keyword))
{
SetWindowText(Dialog, "No exact match for keyword!");
PushButton(SearchDlg, IDCANCEL, TRUE);
return FALSE;
}
// See how many topics matched
HWND Topics = GetDlgItem(SearchDlg, 0x6F);
int Count = ListBox_GetCount(Topics);
// if multiple topics for this keyword
if(Count > 1)
{
for(int i=0; i < Count; ++i)
{
char Item[256];
memset(Item, 0, sizeof(Item));
ListBox_GetText(Topics, i, Item);
// if we found a match
if(!strcmpi(Item, Title))
{
// then select it and press Goto button
ListBox_SetCurSel(Topics, i);
PushButton(SearchDlg, 115, TRUE);
return TRUE;
}
}
// no match, have to fail
PushButton(Topics, IDCANCEL, TRUE);
return FALSE;
}
// now go to the topic...
PushButton(SearchDlg, 115, TRUE);
MessagePump();
return TRUE;
}
static int ShowTopic(HWND Dialog, int LbIndex)
{
SetWindowText(Dialog, "enter ShowTopic()");
int Result = TRUE;
HWND Help = FindWindow("MS_WINHELP", 0);
// MakeActive(Dialog);
int Topic = 0x7FFF & (int)ListBox_GetItemData(
GetDlgItem(Dialog, ID_TOPICTITLES), LbIndex);
ThisTopic.Load(CurrentInstance, Topic);
char Keyword[128];
ThisTopic.GetKeyword(Keyword, sizeof(Keyword));
char Title[128];
ThisTopic.GetTitle(Title, sizeof(Title));
WinHelp(Dialog, SelectedFile, HELP_PARTIALKEY,
(DWORD)Keyword);
MakeActive(Help);
// pick a control that would exist in the search dialog,
// but not in some random error dialog...
int SearchId = IsHelp32 ? 0x407 : 116;
HWND SearchDlg = GetHelpDialog(SearchId);
/* if we are using 32-bit WinHelp, and if more than one
* topic matches this keyword, WinHelp displays a different
* dialog, the "Topics Found" dialog
*/
if(!SearchDlg && IsHelp32)
{
MakeActive(Help);
SearchDlg = GetHelpDialog(0x6F);
if(!SearchDlg)
{
MessagePump(500);
SearchDlg = GetHelpDialog(0x6F);
}
}
// if some other dialog came up, assume it's an error!
if(!SearchDlg && GetHelpDialog())
{
MessageBox(NULL, IsHelp32
?"Error in searching .hlp file! (32-bit WinHelp)"
: "Error in searching .hlp file!", "AnnTater", MB_OK);
// push cancel button and hope for the best.
PushButton(GetHelpDialog(), IDCANCEL, TRUE);
return -1;
}
// if no exact match, then search dialog will appear
if(SearchDlg)
{
if(IsHelp32)
{
SetWindowText(Dialog, "calling MatchTopic32");
if(!MatchTopic32(Dialog, SearchDlg, Title))
Result = FALSE;
}
else
{
SetWindowText(Dialog, "calling MatchTopic16");
if(!MatchTopic16(Dialog, SearchDlg, Title, Keyword))
Result = FALSE;
}
// if no match, then dismiss search dialog
if(Result == FALSE)
PushButton(SearchDlg, IDCANCEL, TRUE);
}
MessagePump();
return Result;
}
void DisplayItem(HWND Dialog, int Index)
{
int TopicNum = 0x7FFF & SendDlgItemMessage(Dialog,
ID_TOPICTITLES, LB_GETITEMDATA, Index, 0);
ThisTopic.Load(CurrentInstance, TopicNum);
/* set edit control text */
SendDlgItemMessage(Dialog, ID_TOPICTEXT,
EM_SETSEL, 1, MAKELPARAM(0,-1));
char*Buffer = new char[8*1024];
if(Buffer)
{
Buffer[0] = '\0';
ThisTopic.GetText(Buffer, 8*1024);
SendDlgItemMessage(Dialog, ID_TOPICTEXT, EM_REPLACESEL,
0, (LPARAM)Buffer);
ThisTopic.GetTitle(Buffer, 8*1024);
SetDlgItemText(Dialog, ID_TOPIC_TITLE, Buffer);
ThisTopic.GetKeyword(Buffer, 8*1024);
SetDlgItemText(Dialog, ID_TOPIC_KEYWORD, Buffer);
delete[] Buffer;
}
SendDlgItemMessage(Dialog, ID_TOPICTEXT, EM_SETSEL, 0, 0);
SendDlgItemMessage(Dialog, ID_TOPICTEXT, EM_LINESCROLL, 0,
MAKELPARAM(-255, 0));
}
void CheckItem(HWND Dialog, int Item)
{
HWND Listbox = GetDlgItem(Dialog, ID_TOPICTITLES);
// add a checkmark to this item
int Old = ListBox_GetItemData(Listbox, Item);
ListBox_SetItemData(Listbox, Item, Old|0x8000);
// make sure it is not selected
ListBox_SetSel(Listbox, FALSE, Item);
ListBox_SetTopIndex(Listbox, (Item < 3) ? 0 : Item - 3);
// schedule a redraw
InvalidateRect(Listbox, NULL, FALSE);
}
static BOOL CopySelections(HWND Dialog)
{
char *Buffer, *Text;
LRESULT Count;
int *Items, i;
// HWND Help = FindHelp();
StopLoop = FALSE;
Count = SendDlgItemMessage(Dialog, ID_TOPICTITLES,
LB_GETSELCOUNT, 0, 0);
if(Count == 0)
return FALSE;
Items = (int *)malloc(sizeof(int *)*(int)Count);
if(!Items)
{
MessageBox(Dialog, "Out of memory!", "AnnTater", MB_OK);
return FALSE;
}
SendDlgItemMessage(Dialog, ID_TOPICTITLES,
LB_GETSELITEMS, (WPARAM)Count, (LPARAM)Items);
Buffer = (char *)malloc(1024*16);
if(!Buffer)
{
MessageBox(Dialog, "Out of memory!", "AnnTater", MB_OK);
return FALSE;
}
Text = (char *)malloc(1024*16);
if(!Text)
{
free(Buffer);
MessageBox(Dialog, "Out of memory!", "AnnTater", MB_OK);
return FALSE;
}
int j;
for(i= 0; i < Count && Always != CANCEL; ++i)
{
if(StopLoop)
break;
DisplayItem(Dialog, Items[i]);
int Status = ShowTopic(Dialog, Items[i]);
if(Status == FALSE)
continue;
else if(Status == -1)
break;
/* open annotation window */
WinHelp(Dialog, SelectedFile, HELP_COMMAND, (DWORD)"Annotate()");
WDJ_EmptyClipboard();
HWND AnnDlg = GetHelpDialog();
for(j=0; j < 2000 && !AnnDlg; ++j)
{
SetWindowText(Dialog, "Waiting for annotation window");
MessagePump();
AnnDlg = GetHelpDialog();
}
if(!AnnDlg)
{
MessageBox(NULL, "Could not open annotation window!", "AnnTater", MB_OK);
return FALSE;
}
SetWindowText(Dialog, "Got annotation window");
MakeActive(AnnDlg);
HWND CopyButton = GetDlgItem(AnnDlg, 0x73);
for(j = 0; j < 2000 && !CopyButton; ++j)
{
MessagePump();
CopyButton = GetDlgItem(AnnDlg, 0x73);
}
if(!CopyButton)
{
MessageBox(NULL, "Anntation window not in expected format!", "AnnTater", MB_OK);
return 0;
}
// read in annotation text
ThisTopic.GetText(Text, 1024*16);
Buffer[0] = '\0';
/* if annotation already exists */
if(IsWindowEnabled(CopyButton))
{
WDJ_EmptyClipboard();
// make annotation dialog copy it to clipboard
PushButton(AnnDlg, 0x73, TRUE);
SetWindowText(Dialog, "Waiting for clipboard data");
while(!WDJ_GetClipboardText(Buffer, 1024*16))
MessagePump();
SetWindowText(Dialog, "Got clipboard data");
if(strstr(Buffer, Text))
{
PushButton(AnnDlg, IDCANCEL, TRUE);
CheckItem(Dialog, Items[i]);
continue;
}
int Result = Always;
if(Always == ASK)
{
MakeActive(Dialog);
Result = DialogBox(CurrentInstance, "Clobber",
AnnDlg, ClobberDialog);
SetWindowText(Dialog, "back from helper dialog");
}
if(Result == CANCEL || Result == SKIP)
{
PushButton(AnnDlg, IDCANCEL, TRUE);
continue;
}
else if(Result == APPEND)
;
else if(Result == REPLACE)
Buffer[0] = '\0';
}
strcat(Buffer, Text);
if(WDJ_SetClipboardText(Buffer))
{
MakeActive(AnnDlg);
// do copy from clipboard to annotation
PushButton(AnnDlg, 0x74, TRUE);
// do save of annotation
PushButton(AnnDlg, 0x01, TRUE);
MessagePump(500);
CheckItem(Dialog, Items[i]);
}
else
{
MessageBox(NULL, "Could not set clipboard text", "", MB_OK);
PushButton(AnnDlg, IDCANCEL, TRUE);
MessagePump(1000);
}
}
free(Text);
free(Items);
free(Buffer);
StopLoop = FALSE;
return TRUE;
}
HWND WindowFromInstance(HINSTANCE Instance)
{
HWND Rover = GetWindow(GetDesktopWindow(), GW_CHILD);
while(Rover)
{
if(Instance == (HINSTANCE)GetWindowInstance(Rover))
return Rover;
else
Rover = GetWindow(Rover, GW_HWNDNEXT);
}
return (HWND)0;
}
static void SetCurDir(const char* In)
{
char* BSlash, *FSlash, *Slash;
char Path[256];
strcpy(Path, In);
BSlash = strrchr(Path, '\\');
FSlash = strrchr(Path, '/');
if(BSlash)
Slash = BSlash;
if(FSlash && !Slash)
Slash = FSlash;
else if(FSlash && Slash && FSlash > Slash)
Slash = FSlash;
if(Slash)
{
*Slash = '\0';
chdir(Path);
if(Path[1] == ':')
{
int Drive = (toupper(Path[0]) - 'A')+1;
if(Drive > 0 && Drive <= 26)
_chdrive(Drive);
}
}
}
static BOOL OnMainDialogCommand(HWND Dialog, UINT Notify,
int ControlId, HWND Control)
{
if(ControlId == IDOK || ControlId == IDCANCEL)
{
EndDialog(Dialog, ControlId == IDOK);
return FALSE;
}
else if(ControlId == ID_HELP && Notify == BN_CLICKED)
{
static char*Help =
"AnnTater: The Windows Developer's Journal helpfile annotater.\r\n"
"Use at your own risk!\r\n\r\n"
"First, select the type of helpfile you want to annotate. "
"If AnnTater cannot locate the file, press the Locate button "
"to specify where it resides. Next, select one or more "
"annotations (or press the Select All button). Finally, "
"press Copy to install your selections in the help file "
"(then stand well back). You may want to back up your "
".ann file before starting this process. ";
MessageBox(Dialog, Help, "AnnTater", MB_OK);
}
else if(ControlId == ID_FIND_FILE && Notify == BN_CLICKED)
{
HWND Combo = GetDlgItem(Dialog, ID_FILES);
char File[256];
char Key[128];
int Index = ComboBox_GetCurSel(Combo);
strcpy(File,
(const char*)ComboBox_GetItemData(Combo, Index)
);
strcpy(Key, File);
OPENFILENAME DialogArgs;
memset(&DialogArgs, 0, sizeof(DialogArgs));
DialogArgs.lStructSize = sizeof(DialogArgs);
DialogArgs.hwndOwner = Dialog;
char Filter[256];
memset(Filter, 0, sizeof(Filter));
strcpy(Filter, "Selected help file");
strcpy(Filter+strlen(Filter)+1, File);
DialogArgs.lpstrFilter = Filter;
DialogArgs.nFilterIndex = 1;
char Title[256];
wsprintf(Title, "Locate selected .hlp file (%s)", File);
DialogArgs.lpstrTitle = Title;
DialogArgs.lpstrFile = File;
DialogArgs.nMaxFile = 256;
DialogArgs.Flags = OFN_FILEMUSTEXIST | OFN_SHOWHELP;
if(GetOpenFileName(&DialogArgs))
{
WritePrivateProfileString("AnnTater", Key, File, "wdj.ini");
strcpy(SelectedFile, File);
PostCommand(Dialog, GetDlgItem(Dialog, ID_FILES),
ID_FILES, CBN_SELCHANGE);
}
}
else if(ControlId == ID_FILES && Notify == CBN_SELCHANGE)
{
char File[256];
File[0] = '\0';
int Index = ComboBox_GetCurSel(Control);
if(Index != CB_ERR)
{
strcpy(File,
(const char*)ComboBox_GetItemData(Control, Index)
);
// new .hlp file selected, attempt to set path
if(!FindHelpFile(Dialog, File))
return TRUE;
LoadTitles(GetDlgItem(Dialog, ID_TOPICTITLES), File);
SetDlgItemText(Dialog, ID_TOPIC_KEYWORD, "");
SetDlgItemText(Dialog, ID_TOPIC_TITLE, "");
SetDlgItemText(Dialog, ID_TOPICTEXT, "");
WinHelp(Dialog, SelectedFile, HELP_QUIT, 0);
MessagePump();
// SetCurDir(SelectedFile);
WinHelp(Dialog, SelectedFile, HELP_CONTENTS, 0);
InitHelpVersion();
MessagePump();
MoveWindow(FindWindow("MS_WINHELP", NULL),
0, 0,
100 + GetSystemMetrics(SM_CXSCREEN)/3,
100 + GetSystemMetrics(SM_CYSCREEN)/3, TRUE);
MakeActive(Dialog);
}
}
else if(ControlId == ID_COPY)
{
Always = ASK;
if(InCopy)
{
StopLoop = TRUE;
return TRUE;
}
InCopy = TRUE;
SetWindowText(Control, "Stop copy!");
CopySelections(Dialog);
SetWindowText(Control, "Copy");
InCopy = FALSE;
SetWindowText(Dialog, "Windows Developer's Journal Annotater");
MakeActive(Dialog);
return FALSE;
}
else if(ControlId == ID_SELECTALL)
{
int Count = SendDlgItemMessage(Dialog, ID_TOPICTITLES,
LB_GETCOUNT, 0, 0);
SendDlgItemMessage(Dialog, ID_TOPICTITLES, LB_SELITEMRANGE, 1,
MAKELPARAM(0, Count-1));
int Index = SendDlgItemMessage(Dialog, ID_TOPICTITLES,
LB_GETSELCOUNT, 0, 0);
EnableControl(Dialog, ID_COPY, Index != 0);
return FALSE;
}
else if(ControlId == ID_TOPICTITLES)
{
/* if selection changes, update edit box */
if(Notify == LBN_SELCHANGE)
{
LRESULT Index;
/* enable/disable buttons, if we have selections or not */
Index = SendDlgItemMessage(Dialog, ID_TOPICTITLES,
LB_GETSELCOUNT, 0, 0);
EnableControl(Dialog, ID_COPY, Index != 0);
if(Index != 0)
{
/* load edit control with text from sel with caret */
Index = SendDlgItemMessage(Dialog, ID_TOPICTITLES,
LB_GETCARETINDEX, 0, 0L);
ShowTopic(Dialog, Index);
SetWindowText(Dialog, "Windows Developer's Journal Annotater");
DisplayItem(Dialog, Index);
MakeActive(Dialog);
}
else
ThisTopic.Clear();
}
return TRUE;
}
return TRUE; /* TRUE == we didn't process the message */
}
/* InitFileList - initialize combo-box of files.
*
* Here we make a pass over all the annotations and
* form the list of the names of the files that are
* referred to by these annotations. The filenames
* are stored in a combobox.
*/
void InitFileList(HWND Dialog, int ComboId)
{
HWND Combo = GetDlgItem(Dialog, ComboId);
int Index;
// Index = ComboBox_AddString(Combo, "MFC (mfc30.hlp)");
// ComboBox_SetItemData(Combo, Index, "mfc30.hlp");
Index = ComboBox_AddString(Combo, "Win32 API (win32.hlp, api32.hlp)");
ComboBox_SetItemData(Combo, Index, "win32.hlp");
Index = ComboBox_AddString(Combo, "Windows 3.1 API (win31wh.hlp)");
ComboBox_SetItemData(Combo, Index, "win31wh.hlp");
}
BOOL CALLBACK __export MainDialog(HWND Dialog, UINT Message,
WPARAM Param1, LPARAM Param2)
{
if(Message == WM_INITDIALOG)
{
EnableControl(Dialog, ID_COPY, FALSE);
EnableControl(Dialog, ID_SELECTALL, FALSE);
InitFileList(Dialog, ID_FILES);
ComboBox_SetCurSel(GetDlgItem(Dialog, ID_FILES), 0);
PostCommand(Dialog, GetDlgItem(Dialog, ID_FILES),
ID_FILES, CBN_SELCHANGE);
return TRUE;
}
else if(Message == WM_TIMER)
{
MakeActive(Dialog);
KillTimer(Dialog, 1);
BringWindowToTop(Dialog);
SetActiveWindow(Dialog);
SetFocus(Dialog);
}
else if(Message == WM_USER + 999)
{
MakeActive(Dialog);
}
else if(Message == WM_COMMAND)
{
return DialogCommand(OnMainDialogCommand,
Dialog, Param1, Param2);
}
else if(Message == WM_DESTROY && SelectedFile[0])
WinHelp(Dialog, SelectedFile, HELP_QUIT, 0);
return FALSE; /* FALSE == we didn't process msg */
}
#ifdef __BORLANDC__
#pragma argsused
#endif
int WINAPI WinMain(HINSTANCE Instance, HINSTANCE Previous,
LPSTR CommandLine, int ShowCommand)
{
CurrentInstance = Instance;
InitCheckList(Instance);
DialogBox(Instance, MAIN_DLG, NULL, MainDialog);
return 0;
}